<template>
  <div>
    <NewQueryForm v-if="mode === 0 && search" ref="queryFormRef" :columns="columns" :formProps="formProps"
      :defaultShowItems="getProps.queryFormDefaultShowItemCount" @toggle-advanced="(e) => emit('toggle-advanced', e)"
      @query="refreshTable" :searchBtnType="searchBtnType" />
    <Card :title="mode == 0 && !slots.title ? headerTitle : undefined">
      <template #title v-if="mode === 1">
        <NewQueryForm v-if="search" ref="queryFormRef" :columns="columns" :formProps="formProps"
          :defaultShowItems="getProps.queryFormDefaultShowItemCount" @toggle-advanced="(e) => emit('toggle-advanced', e)"
          @query="refreshTable" :searchBtnType="searchBtnType" />
      </template>
      <template #title v-if="slots.title">
        <slot name="title">{{ headerTitle }}</slot>
      </template>
      <template #extra v-if="showCardHeader">
        <!--        <div class="extra">-->
        <Space>
          <template v-if="slots.action">
            <slot name="action"></slot>
          </template>
          <template v-if="slots.toolbar">
            <slot name="toolbar"></slot>
          </template>
          <template v-else>
            <VxeToolbar ref="toolBarRef" v-bind="toolbar" />
          </template>
        </Space>
        <!--        </div>-->
      </template>
      <VxeGrid ref="tableRef" v-bind="getBindValues" @checkbox-change="checkboxChangeFn" @checkbox-all="checkboxAllFn" />
    </Card>
  </div>
</template>

<script lang="tsx">
import {
  computed,
  defineComponent,
  getCurrentInstance,
  nextTick,
  onMounted,
  provide,
  reactive,
  ref,
  Ref,
  toRefs,
  unref,
} from 'vue';
import {
  VxeGridInstance,
  VxeGridPropTypes,
  VxeTablePropTypes,
  VxeToolbarInstance,
} from 'vxe-table';
import NewQueryForm from './components/query-form/index.vue';
import TableAction from './components/table-action.vue';
import superTableProps, { LayoutMode, TableProps } from './props';
import { createTableContext } from './hooks';
import { Card, Space } from 'ant-design-vue';
import { TableColumn } from './typing';
import { omit } from 'lodash-es';
import { dict } from '@/framework/core/dict';
import { verifyAuth } from '@/framework/core/permission';

export default defineComponent({
  name: 'SuperTable',
  components: {
    Card,
    Space,
    NewQueryForm,
    TableAction,
  },
  inheritAttrs: false,
  props: superTableProps,
  emits: ['toggle-advanced', 'checkbox-change', 'checkbox-all'],
  setup(props, { emit, slots }) {
    createTableContext(getCurrentInstance()!);
    provide('layoutMode', props.mode);
    const tableRef = ref() as Ref<VxeGridInstance>;
    const queryFormRef = ref() as Ref<typeof NewQueryForm>;
    const toolBarRef = ref() as Ref<VxeToolbarInstance>;

    const innerPropsRef = ref<Partial<TableProps>>();

    const getProps = computed(() => {
      const result = { ...props, ...unref(innerPropsRef) };
      if (props.mode === LayoutMode.SIMPLE && props.queryFormDefaultShowItemCount < 5) {
        result.queryFormDefaultShowItemCount = 5;
      }
      return result;
    });

    const state = reactive({
      expandItemRefs: {},
      tableData: [] as any[], // 表格数据
      loading: false, // 表格加载
    });
    const checkboxChangeFn = (params) => {
      emit('checkbox-change', params);
    };
    const checkboxAllFn = (params) => {
      emit('checkbox-all', params);
    };
    const getBindValues = computed(() => {
      const props = unref(getProps);
      const columns = (props.columns as TableColumn[]).filter(
        (n) => !n.hideInTable && (!n.perm || verifyAuth(n.perm)),
      );
      columns.forEach((column) => {
        if (column.dict) {
          column.formatter = (params) => {
            return dict.filter({ key: column.dict, value: params.cellValue, fields: 'name' });
          };
        }
        if (column.slots) {
        } else {
          column.slots = {};
        }
        if (column.bodyCell) {
          column.slots.default = column.bodyCell;
        }

        if (column.headerCell) {
          column.slots.header = column.headerCell;
        }

        if (column.actions && column.field === '$action') {
          const actions = column.actions as Function;
          column.slots.default = (params) => (
            <TableAction actions={actions(params)}></TableAction>
          );
        }
      });
      const proxyConfig: VxeGridPropTypes.ProxyConfig = {};
      const pagerConfig: VxeGridPropTypes.PagerConfig = {
        enabled: false,
        layouts: [
          'PrevJump',
          'PrevPage',
          'Jump',
          'PageCount',
          'NextPage',
          'NextJump',
          'Sizes',
          'Total',
        ],
        currentPage: 1,
        pageSize: 10,
        pagerCount: 5,
        align: 'right',
        border: false,
        background: false,
        perfect: false,
        pageSizes: props.pageSizeConfig,
        autoHidden: false,
      };
      const filterConfig: VxeTablePropTypes.FilterConfig = {};
      if (props.dataRequest) {
        proxyConfig.enabled = true;
        proxyConfig.autoLoad = props.autoLoad;
        if (props.pager) {
          proxyConfig.props = {
            // @Notice 面向HT-Frame框架 BaseResponse 返回体
            result: 'data',
            total: 'total',
          };
        } else {
          proxyConfig.props = {
            list: 'data',
          };
        }

        proxyConfig.ajax = {
          query: props.dataRequest,
        };
        if (props.dataRequestAll) {
          proxyConfig.ajax.queryAll = props.dataRequestAll;
        }
      }

      if (props.remoteFilter) {
        filterConfig.remote = true;
        proxyConfig.filter = true;
      }

      if (props.pager) {
        pagerConfig.enabled = true;
      }

      let propsData: Recordable = {
        ...props, // 继承所有属性
        columns,
        proxyConfig,
        pagerConfig,
        loading: state.loading,
        filterConfig,
      };

      propsData = omit(propsData, ['class', 'onChange']);
      return propsData;
    });

    /**
     * 参数用反射获取
     * @see getFormModel
     */
    const queryTable = () => {
      tableRef.value.commitProxy('query');
    };

    const refreshTable = () => {
      tableRef.value.commitProxy('reload');
    };

    onMounted(() => {
      if (!slots.toolbar && props.showCardHeader) {
        nextTick(() => {
          // 将表格和工具栏进行关联
          const $table = tableRef.value;
          const $toolbar = toolBarRef.value;
          $table.getRefMaps().refTable.value.connect($toolbar);
        });
      }
    });

    /**
     * 方便FetchMethod获取请求参数
     */
    const getFormModel = () => {
      return queryFormRef.value.getFormModel();
    };

    /**
     *
     */
    const getCheckboxRecords = () => {
      return tableRef.value.getCheckboxRecords();
    };
    const getCurrentRecord = () => {
      return tableRef.value.getCurrentRecord();
    };

    const getProxyInfo = () => {
      return tableRef.value.getProxyInfo();
    };

    const openExport = () => {
      return tableRef.value.openExport();
    };
    return {
      ...toRefs(state),
      emit,
      slots,
      tableRef,
      queryFormRef,
      toolBarRef,
      // defaultSlots,
      getProps,
      getBindValues,
      queryTable,
      refreshTable,
      getFormModel,
      getCheckboxRecords,
      getCurrentRecord,
      checkboxChangeFn,
      checkboxAllFn,
      getProxyInfo,
      openExport,
      LayoutMode,
    };
  },
});
</script>

<style scoped lang="less">
:deep(.ant-card-head-title) {
  padding: 0px;
  margin: 0.6em 0;
}

:deep(.ant-card-extra) {
  padding: 0px;
}
</style>
